package com.efast.cafe.portal.security.core.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.MDC;
import org.slf4j.event.Level;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import com.efast.cafe.commponent.log.ext.CafeLogger;
import com.efast.cafe.commponent.log.ext.CafeLoggerFactory;
import com.efast.cafe.framework.bean.ResultBean;
import com.efast.cafe.framework.constant.CommonConstant;
import com.efast.cafe.framework.constant.SecurityConstant;
import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.portal.bean.base.BaseCompanyInfoBean;
import com.efast.cafe.portal.bean.common.ParameterResultBean;
import com.efast.cafe.portal.bean.common.PortalUserDetails;
import com.efast.cafe.portal.bean.common.PortalUserSecurityBean;
import com.efast.cafe.portal.entity.company.PortalCompanyRole;
import com.efast.cafe.portal.security.core.AuthenticationFactory;
import com.efast.cafe.portal.security.core.AuthenticationTypeService;
import com.efast.cafe.portal.service.base.IBaseCompanyInfoService;
import com.efast.cafe.portal.service.common.IParameterService;
import com.efast.cafe.portal.service.common.IResourceService;
import com.efast.cafe.portal.service.company.IPortalCompanyUserService;
import com.efast.cafe.util.IpAddressUtil;
import com.efast.cafe.util.StringUtil;

import net.sf.json.JSONObject;


@Component("pwdAuthenticationProcessor")
public class PwdAuthenticationProcessor implements AuthenticationTypeService{
	
	private CafeLogger logger = CafeLoggerFactory.getLogger(PwdAuthenticationProcessor.class);
	
	@Autowired
	private IPortalCompanyUserService portalCompanyUserService;
	
	
	@Autowired
	private IResourceService portalResourceService;
	
	@Autowired
	private IParameterService parameterService;
	
	@Autowired
	private IBaseCompanyInfoService baseCompanyInfoService;
	
	
	

	@Override
	public UsernamePasswordAuthenticationToken authentication(HttpServletRequest request) {
		String companyCode = request.getParameter(AuthenticationFactory.SPRING_SECURITY_FORM_COMPANYCODE_KEY);
		String username = request.getParameter(AuthenticationFactory.SPRING_SECURITY_FORM_UNAME_KEY);
		String password = request.getParameter(AuthenticationFactory.SPRING_SECURITY_FORM_PWD_KEY);
		
		if (StringUtil.isEmpty(companyCode)) {
			throw new AuthenticationServiceException(SecurityConstant.ERROR_CODE.COMPANY_EMPTY);
		}
		if (StringUtil.isEmpty(username)) {
			throw new AuthenticationServiceException(SecurityConstant.ERROR_CODE.USER_EMPTY);
		}
		if (StringUtil.isEmpty(password)) {
			throw new AuthenticationServiceException(SecurityConstant.ERROR_CODE.PWD_EMPTY);
		}
		username = username.trim();
		UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
				companyCode+CommonConstant.J_COMPANY_USERNAME_SEPARATOR+username, password);
		return authRequest;
	}

	

	
	   
	
	   
	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication)throws IOException, ServletException {
		PortalUserDetails userDetail = (PortalUserDetails)authentication.getPrincipal();
		PortalUserSecurityBean user = userDetail.getUser();
		MDC.put(CommonConstant.USERNAME_FIELD, user.getUname());
		MDC.put(CommonConstant.COMPANYCODE_FIELD, user.getCompany_code());
		MDC.put("clientIP",IpAddressUtil.getIpAdrress(request));
		HttpSession session = request.getSession();
		List<String> roleNames = new ArrayList<>();
		List<PortalCompanyRole> roles = portalCompanyUserService.queryUserHasRoleList(user.getUname(),user.getCompany_code());
		roles.forEach(r->{roleNames.add(r.getRoleName());});
		user.setRoleNames(roleNames);
		session.setAttribute(CommonConstant.PORTAL_USER_OBJECT, user);
		session.setAttribute(CommonConstant.CURRENT_LOGIN_USER_NAME_KEY, user.getUname());
		session.setAttribute(CommonConstant.CURRENT_LOGIN_USER_COMPANYCODE_KEY, user.getCompany_code());
		HashSet<String> checkauthSet = portalResourceService.queryPurviewPathByCompanyUserAndRoleDB(user.getCompany_code(), user.getUname());
		HashSet<String> allPurvewPathSet = portalResourceService.queryAllPurviewPathDB();
		session.setAttribute(CommonConstant.CURRENT_LOGIN_USER_PURVIEWSET_SESSIONKEY, checkauthSet);
		session.setAttribute(CommonConstant.CURRENT_LOGIN_USER_ALLPURVIEWSET_SESSIONKEY, allPurvewPathSet);
		session.setAttribute("request_locale", "zh_CN");
		JSONObject res = new JSONObject();
		JSONObject jo = new JSONObject();
		jo.put("companyCode", user.getCompany_code());
		jo.put("username", user.getUname());
		jo.put("email", StringUtil.isNotBlank(user.getEmail()) ? user.getEmail() : "");
		jo.put("phone", StringUtil.isNotBlank(user.getPhone()) ? user.getPhone() : "");
		jo.put("type", StringUtil.isNotBlank(user.getType()) ? user.getType() : "");
		jo.put("isManager", user.getDefault_user() != null ? user.getDefault_user() : 0);
		jo.put("userLevel", StringUtil.isNotBlank(user.getUser_level()) ? user.getUser_level() : "");
		jo.put("sex", user.getSex() != null ? user.getSex() : null);
		jo.put("realName", StringUtil.isNotBlank(user.getReal_name()) ? user.getReal_name() : user.getUname());
		jo.put("roleList", roleNames);
		res.put("success", true);
		List<ParameterResultBean> params =parameterService.getParameters(CommonConstant.ParameterGroups.WEB_INDEX, user.getCompany_code(), user.getUname());
		BaseCompanyInfoBean companyInfo = baseCompanyInfoService.queryByCode(user.getCompany_code());
		jo.put("companyName", companyInfo.getCompany_name());
		jo.put("generateFormId", companyInfo.getGenerateFormId());
		jo.put("params", params);
		res.put("object", jo);
		res.put("errorCode", "");
		res.put("errorMessage", "");
		String token = UUID.randomUUID().toString();
		res.put("token", token);
		session.setAttribute("token", token);
		
		logger.cacheLog(Level.INFO, jo.toString(), "登录系统");
		
    	response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		response.getWriter().print(res.toString());
	}

	
	    
	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException exception)throws IOException, ServletException {
		JSONObject jo = new JSONObject();
		jo.put("success", false);
		
		String errorCode = "2002";
		
		Throwable throwable = exception.getCause();
		
		
		if(throwable!=null && throwable instanceof ServiceException){
			ServiceException bad = (ServiceException) throwable;
			errorCode = bad.getCode();
		}else if (exception instanceof AuthenticationServiceException){
			AuthenticationServiceException ex = (AuthenticationServiceException)exception;
			errorCode = ex.getMessage();
			if(errorCode.equals("-1")){
				jo.put("message",  "Authentication method not supported: " + request.getMethod()); 
			}
		}
		//2002 密码错误
		jo.put("errorCode", errorCode);
		
		//response
		response.setCharacterEncoding("UTF-8"); 
		 response.setContentType("application/json; charset=utf-8");
		 response.getWriter().print(jo.toString());
	}

	
	    
	@Override
	public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication)throws IOException, ServletException {
		ResultBean res = new ResultBean(true, "");
		response.setCharacterEncoding("UTF-8"); 
		response.setContentType("application/json; charset=utf-8");
        response.getWriter().print(JSONObject.fromObject(res).toString());
	}

}
